﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Engine.Dtd.Schema;
using Engine.Sgml.Merging;

namespace Engine.Sgml.Allocation {
    internal static class AllocationHelper {
        public static SElement CreateWrapper(SElement parent, DElementDeclaration declaration) {
            SElement wrapper = parent.Nodes.Push();
            wrapper.Clear();
            wrapper.Name = SName.Get(declaration.Name);
            wrapper.DName = declaration.Name;
            wrapper.Declaration = declaration;
            wrapper.NodeType = SgmlNodeType.Element;
            wrapper.Parent = parent;
            return wrapper;
            }

        public static void Surround(InconsistentBlock block, SElement wrapper) {
            SElement element = block.FirstElement;
            wrapper.Move(element.OrderIndex);
            wrapper.LineNumber = element.LineNumber;
            wrapper.LinePosition = element.LinePosition;
            for (int i = 0; i < block.Count; i++) {
                element = block[i];
                wrapper.Add(element);
                }
            }

        public static IModelGroupsNode FindAncestor(SElement element, SElement ancestor) {
            if (CanFindAncestor(ancestor.Declaration))
                return FindAncestor(element, ancestor.Declaration.ContentModel);
            else
                return null;
            }

        private static IModelGroupsNode FindAncestor(SElement element, DContentModel contentModel) {
            // Произвести поиск в элементах группы которые
            // обязательно должны пристутствовать
            foreach (IModelGroupsNode item in contentModel.Groups)
                if (item.HasDeclaration() &&
                    item.Declaration.ElementType != DElementType.Inline &&
                    item.MustPresent() &&
                    item.Declaration.ContentModel.Exists(element.DName))
                    return item;
            // Если результат не получен 
            // Выполнить поиск среди необязательных элементов группы
            foreach (IModelGroupsNode item in contentModel.Groups)
                if (item.HasDeclaration() &&
                    item.Declaration.ElementType != DElementType.Inline &&
                    !item.MustPresent() &&
                    item.Declaration.ContentModel.Exists(element.DName))
                    return item;
            return null;
            }

        private static bool CanFindAncestor(DElementDeclaration declaration) {
            return declaration != null && declaration.ContentModel.ContentType != DContentModelType.Empty;
            }

        }
    }
